package fr.zombieGame;

/**
 * Polytech' Nice - Sophia Antipolis / SI3 / POO2
 * Annee 2011_2012
 *
 * OMG Zombies !
 *
 * Classe Helicoptere : modelisation d'un helico
 *                      Helicoptere herite de Personnage
 *
 * @author J. Harnetiaux et J. Lionne
 */

import java.util.Iterator;
import java.util.List;
import java.util.Random;
import fr.comportement.*;

import com.simulator.*;

public class Helicoptere extends Personnage{

    public Helicoptere(String nom, int pointsDeVie, final Field field, final Location location) {
        super(nom, pointsDeVie, field, location);
        force = 5;

        this.deplacement = new Deplacement() {
            private static final int VITESSE = 30;

            public void bouger(Personnage perso) {
                Location newLocation = field.freeAvailableLocation(location, VITESSE);
                if (newLocation != null) setLocation(newLocation);
                else setMort();
            }

            public int getVitesse() {
                return VITESSE;
            }
        };
        this.espritCombatif = new CombatEcraser();
        this.soutien = new PremiersSoins();

    }

    /**
     *  L'hélicoptère ne peut pas mourir
     */
    @Override
    public void setMort(){ }

    /**
     *  L'hélicoptère ne peut pas crier
     */
    @Override
    public void crier(String s){ }


    /**
     * Change la strategie de deplacement de l'hélicoptère
     * L'hélicoptère ne peut pas changer de déplacement
     */
    @Override
    public void setDeplacement(Deplacement deplacement) { }

    /**
     * Change la strategie de combat de l'humain
     * Un humain ne peut pas se battre a mains nues ou mordre un ennemie
     */
    @Override
    public void setEspritCombatif(EspritCombatif espritCombatif) {

        if(espritCombatif instanceof Morsure || espritCombatif instanceof CombatMainsNues) return;

        // Appliquer la strategie de combat
        //
        this.espritCombatif = espritCombatif;
    }

    /**
     * Change la strategie de soutient de l'humain
     */
    @Override
    public void setSoutien(Soutien soutien) {
        // Appliquer la strategie de soutien
        //
        this.soutien = soutien;
    }

    /**
     * Méthode pour définir l'esprit Combatif contre les Vampires avec le pieu
     */
    private void aideContreVampire(Personnage perso){
        perso.espritCombatif = new CombatPieux();
    }
    /**
     * Méthode pour définir l'esprit Combatif contre les Zombies avec l'eau bénite
     */
    private void aideContreZombie(Personnage perso){
        perso.espritCombatif = new CombatEauBenite();
    }

    /**
     * Méthode pour définir la forme de soutien soins
     */
    private void soutienSoins(Personnage perso){
        perso.soutien = new PremiersSoins();
    }
    /**
     * Méthode pour définir la forme de soutien nourriture
     */
    private void soutienNourriture(Personnage perso){
        perso.soutien = new Nourriture();
    }

    @Override
    public void finDeTour() {
        estVivant = true;
    }

    /**
     * Joue le comportement de l'hélicoptère
     */
    public void jouer() {
        // L'helicoptere bouge à chaque tour
        // Se deplacer à une localisation ou se trouve un ennemi
        //
        Location localisation = trouverEnnemi(location);
        if (localisation == null) {
            // Pas d'ennemi aux alentours - se deplacer sur une localisation dispo
            //
            localisation = field.freeAvailableLocation(location, deplacement.getVitesse());
        }
       
        // Vérifier s'il est possible de bouger
        //
        if (localisation != null) setLocation(localisation);

        // Appliquer la fin de tour
        //
        this.appelerFinDeTour();
    }

    // POUR AVOIR ALEATOIREMENT UNE AIDE CONTRE VAMPIRE OU ZOMBIE, DES SOINS OU DE LA NOURRITURE
    public void randomHelp(Personnage perso){
        Random rand = new Random();
        if(rand.nextBoolean()) {
            aideContreVampire(perso);
            soutienSoins(perso);
        }
        else {
            aideContreZombie(perso);
            soutienNourriture(perso);
        }
    }

    @Override
    public void rencontrerPersonnage(Personnage perso){
        if(perso instanceof Humain){
            randomHelp(perso);
            soutien.soutenir((Humain)perso);
        }
        else {
            espritCombatif = new CombatEcraser();
            espritCombatif.combat(this, perso, force);
        }
    }

    /**
     * Trouve un ennemi dans les localisations disponibles
     * Dans le cas de l'hélicoptère, il s'agit en fait d'un humain à aider
     * @param location
     *          Localisation du personnage
     * @return
     *          La localisation de l'humain
     */
    @Override
    protected Location trouverEnnemi(Location location) {
        List<Location> available = field.availableLocations(location, deplacement.getVitesse());
        Iterator<Location> it = available.iterator();
        while (it.hasNext()) {
            Location where = it.next();
            Object perso = field.getObjectAt(where);
                Personnage ennemi = (Personnage) perso;
                if (ennemi != null && ennemi.estVivant()) {
                    Location adjacent = field.freeAdjacentLocation(where);
                    if(adjacent == null) continue;
                    if(ennemi instanceof Humain) this.soutien.soutenir(ennemi);
                    else this.espritCombatif.combat(this, ennemi, force);
                    return adjacent;
                }
        }
        return null;
    }
}
